import React, { useEffect } from 'react';
import { connect, Dispatch } from 'umi';
import './index.less';
import { useEffectOnce } from 'react-use';
import { ConnectProps, ConnectState } from '@/models/connect';
import Home from './home';
import TopToolbar from './projTopToolbar';
import List from './constructComponetList';
import Statistics from './home/left/statistics';
// import Compareview from './Compareview'
import { jsapi, viewUtils } from '@/utils/arcgis';
// import layerCreator from '@/utils/arcgis/layer/layer-creator';
import LineDesignCheck from './lineDesignCheck';
import kls from 'classnames';

// 要素渲染
import ElementRender from './elementRender';
import CitySketch from './citySketch';
import SchemeForm from './schemeForm';
import QualityAndSafety from './qualityAndSafety';
import IntegratedMonitoring from './integratedMonitoring';
import { WORKING_TAB } from '@/models/app';

import BlockInfo from './popupPanel/blockInfo';
import PopupGraph from './popupGraph';
import BuilidngFilter from './popupPanel/builidngFilter';
import VideoPanel from './popupPanel/videoPanel';
import fakePointData from './fakePointData';
// import { initEchartsLayer } from '@/components/content/mainPage/chartLayer/demo2.js';
import createTempLyr from './temp-lyr';

export interface HeaderPropTypes {}

interface ConnectedProps extends ConnectProps {
  isFullScreen: boolean;
  isGlobalProcessRender: boolean;
  curWorkingTab: string;
  dispatch: Dispatch;
}

// @ts-ignore
// window.highlightSelect = null
// 地图点击触发
async function handleLayerClick(view, dispatch) {
  view.on('click', function(event) {
    view.hitTest(event).then(function(response) {
      var result = response.results[0];
      console.log('地图点击触发', response.results[0]);
      setTimeout(() => {
        let esriDom = document.querySelector('.esri-popup__main-container') as HTMLElement;
        if (esriDom) esriDom.style.display = 'none';
      }, 0);
      if (!result) return;

      if (result.graphic.layer.name === 'cameraLayer') {
        console.log(result.graphic.attributes);
        // todo 此处未来可以在这里增加 xy 坐标轴，在不同的地方打开视频
        dispatch({
          type: 'projectPage/updateState',
          payload: {
            curVideoId: result.graphic.attributes.cameraid,
            urlFromCameraLayer: result.graphic.attributes.rtsp || '',
          },
        });
      }

      // 点图层
      if (result.graphic.layer.title === 'wbs_marks') {
        dispatch({
          type: 'projectPage/updateState',
          payload: {
            selectedWbs: result.graphic.attributes.wbsCode,
            selectedId: result.graphic.attributes.id,
            // selectedWbs: result.graphic.attributes['WBS编码'],
          },
        });

        view.whenLayerView(result.graphic.layer).then(function(layerView) {
          // The layerview for the layer

          if (window.highlightSelect) {
            window.highlightSelect.remove();
          }
          window.highlightSelect = layerView.highlight(result.graphic);
        });
      }

      if (result.graphic.layer.type === 'building-scene') {
        if (window.highlightSelect) {
          window.highlightSelect.remove();
        }
        dispatch({
          type: 'projectPage/updateState',
          payload: {
            selectedWbs: result.graphic.attributes['WBS编码'],
            selectedId: '',
          },
        });
      }
    });
  });
}

async function addExtraLayer(dispatch, afterLayerAdd) {
  let layersWillAdd: any[] = [];
  const [TileLayer, FeatureLayer, ElevationLayer] = await jsapi.load([
    'esri/layers/TileLayer',
    'esri/layers/FeatureLayer',
    'esri/layers/ElevationLayer',
  ]);

  // 初始化bim模型

  // 加载用户配置的图层
  dispatch({ type: 'app/initTileLayers' });

  // @ts-ignore
  if (window.cameraLayerUrl) {
    // 监控点图层及其设置
    let cameraLayer = new FeatureLayer({
      name: 'cameraLayer',
      title: 'cameraLayer',
      // @ts-ignore
      url: window.cameraLayerUrl,
      // url: 'https://portal.wccg.tech:9002/to443/server1/rest/services/Hosted/CameraWuxiTest/FeatureServer',
      elevationInfo: {
        mode: 'relative-to-scene',
      },
      popupEnabled: false,
      objectIdField: 'objectid',
      outFields: ['*'],
      fields: [
        {
          name: 'objectid',
          type: 'oid',
        },
        {
          name: 'name',
          type: 'string',
        },
      ],
      labelingInfo: [
        {
          labelExpressionInfo: {
            value: '{name}',
          },
          labelPlacement: 'above-center',
          symbol: {
            type: 'label-3d',
            symbolLayers: [
              {
                type: 'text',
                material: {
                  color: 'white',
                },
                size: 10,
              },
            ],
          },
        },
      ],
    });

    cameraLayer.renderer = {
      type: 'simple',
      symbol: {
        type: 'point-3d', // autocasts as new PointSymbol3D()
        symbolLayers: [
          {
            type: 'icon', // autocasts as new IconSymbol3DLayer()
            resource: {
              href: './images/camera.png',
            },
            size: 20,
            outline: {
              color: 'white',
              size: 2,
            },
          },
        ],

        verticalOffset: {
          screenLength: 20,
          maxWorldLength: 200,
          minWorldLength: 35,
        },

        callout: {
          type: 'line', // autocasts as new LineCallout3D()
          color: 'white',
          size: 2,
          border: {
            color: '#2fb0ff',
          },
        },
      },
    };

    const cameraEffectRenderer = {
      type: 'simple', // autocasts as new SimpleRenderer()
      symbol: {
        type: 'point-3d', // autocasts as new PointSymbol3D()
        symbolLayers: [
          {
            type: 'object', // autocasts as new ObjectSymbol3DLayer()
            resource: {
              primitive: 'cone',
            },
            material: { color: [232, 192, 59, 0.6] },
            width: 400, // width of the symbol in meters
            height: 35,
          },
        ],
      },
      visualVariables: [
        {
          type: 'size',
          axis: 'width-and-depth',
          useSymbolValue: true, // uses the width value defined in the symbol layer (50,000)
        },
        {
          type: 'size',
          axis: 'height',
          useSymbolValue: true, // uses the width value defined in the symbol layer (50,000)
        },
      ],
    };

    let cameraEffectLayer = new FeatureLayer({
      name: 'cameraEffectLayer',
      title: 'cameraEffectLayer',
      // @ts-ignore
      url: window.cameraLayerUrl,
      // url: 'https://portal.wccg.tech:9002/to443/server1/rest/services/Hosted/CameraWuxiTest/FeatureServer',
      elevationInfo: {
        mode: 'relative-to-scene',
      },
      popupEnabled: false,
      objectIdField: 'objectid',
      outFields: ['*'],
      fields: [
        {
          name: 'objectid',
          type: 'oid',
        },
        {
          name: 'name',
          type: 'string',
        },
        {
          name: 'cameraid',
          type: 'string',
        },
      ],
      renderer: cameraEffectRenderer,
      definitionExpression: 'objectid in ("占位")',
    });

    layersWillAdd.push(cameraLayer, cameraEffectLayer);
  }

  const elevLyr = new ElevationLayer({
    // Custom elevation service
    url:
      // 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/MtBaldy_Elevation/ImageServer?f=json',
      'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
  });

  const view = await viewUtils.isViewReady();

  // Add elevation layer to the map's ground.
  view.map.ground.layers.add(elevLyr);

  // 暂时图层
  let tempLyr = await createTempLyr();
  if (tempLyr) {
    layersWillAdd.push(tempLyr);
  }
  view.map.addMany(layersWillAdd);

  afterLayerAdd(view, dispatch);

  setTimeout(() => {
    dispatch({
      type: 'bimmodel/initAllBimModels',
      payload: {
        // skipFirstRender: true,
      },
    }).then(() => {
      dispatch({ type: 'kanban/getInitRender' });
    });
  }, 300);
}

const ProjectPage: React.FC<HeaderPropTypes & ConnectedProps> = ({
  dispatch,
  isFullScreen,
  isGlobalProcessRender,
  curWorkingTab,
  statisticsData,
}) => {
  useEffectOnce(() => {
    // todo
    addExtraLayer(dispatch, handleLayerClick);
    dispatch({
      type: 'kanban/getCurProj',
    }).then(curProj => {
      dispatch({
        type: 'projectPage/getSectionProgress',
      });
      dispatch({
        type: 'projectPage/getTotalProgress',
      });
      dispatch({
        type: 'projectPage/getAllWbs',
      });
      dispatch({
        type: 'monitor/init',
      });
      // 使用当前时间获取进度列表
      dispatch({ type: 'kanban/getProjProgressInfo' });
      setInitCamera(curProj);

      dispatch({
        type: 'projectPage/getStatisticsData',
      });
    });
  });

  useEffect(() => {
    if (!statisticsData) {
      return;
    }

    // @ts-ignore
    let params = new URL(document.location).searchParams;
    let id = params.get('i');
    if (fakePointData[id]) {
      createMarkerLayer(fakePointData[id]);
    }
    // todo 演示用假数据
    return;
    createMarkerLayer([
      ...uniqueArrByField(statisticsData.totalProcessList, 'wbsCode', { type: '进度验收' }),
      ...uniqueArrByField(statisticsData.totalQualityList, 'wbsCode', { type: '质量问题' }),
      ...uniqueArrByField(statisticsData.totalSafetyList, 'wbsCode', { type: '安全巡检' }),
    ]);
  }, [statisticsData]);

  useEffect(() => {
    // initEchartsLayer();
    return () => {
      // @ts-ignore
      window.highlightSelect && window.highlightSelect.remove();
    };
  }, []);

  async function setInitCamera({ lng, lat }) {
    const view = await viewUtils.isViewReady();
    let newConfig = JSON.parse(JSON.stringify(window.appcfg.jsapiConfig.projInitialCamera));
    delete newConfig.position.x;
    delete newConfig.position.y;
    newConfig.position.latitude = lat;
    newConfig.position.longitude = lng;
    view.when(() => {
      setTimeout(() => {
        view.goTo(newConfig, { animate: false });
      }, 1000);
    });
  }

  function getContent(curWorkingTab) {
    switch (curWorkingTab) {
      case WORKING_TAB[0]:
        //  监控集成
        return <IntegratedMonitoring />;

      case WORKING_TAB[1]:
        // 全局渲染的列表
        return (
          <>
            <List />
            <Statistics location="right" />
          </>
        );

      case WORKING_TAB[2]:
        return <QualityAndSafety />;

      case WORKING_TAB[3]:
        return (
          <>
            <LineDesignCheck />
          </>
        );
      case WORKING_TAB[4]:
        return (
          <>
            <ElementRender />
            <CitySketch />
            <SchemeForm />
          </>
        );

      case WORKING_TAB[5]:
      default:
        return <Home />;
    }
  }

  return (
    <div className="project-page">
      <TopToolbar />
      <div
        className={kls('project-page-popup', {
          // 'project-page-popup-left': curWorkingTab === WORKING_TAB[1],
        })}
        style={{ visibility: isFullScreen ? 'hidden' : 'visible' }}
      >
        <BlockInfo />
        <PopupGraph />
        <VideoPanel />
        <BuilidngFilter />
      </div>
      <div style={{ visibility: isFullScreen ? 'hidden' : 'visible' }}>
        {getContent(curWorkingTab)}
      </div>
    </div>
  );
};

// @ts-ignore
export default connect(({ app, projectPage }: ConnectState) => {
  const { isFullScreen, curWorkingTab } = app;
  return {
    isFullScreen,
    curWorkingTab,
    statisticsData: projectPage.statisticsData,
  };
})(ProjectPage);

async function createMarkerLayer(wbsObjArr) {
  // console.log(JSON.stringify(wbsObjArr), '-------00--------');
  // async function createMarkerLayer(wbsObjArr) {
  const [FeatureLayer, Graphic, Point] = await jsapi.load([
    'esri/layers/FeatureLayer',
    'esri/Graphic',
    'esri/geometry/Point',
    //! 非常离谱的在海视微康的hls.min.js加载之后dojo环境会被破坏，在这里预加载吧
    'esri/widgets/Legend',
    'esri/symbols/support/previewSymbol2D',
  ]);

  const graphics = wbsObjArr.map(item => {
    const location = new Point({
      latitude: item.applyLatitude,
      longitude: item.applyLongitude,
    });

    return new Graphic({
      geometry: location,
      attributes: {
        ...item,
        OBJECTID: item.id,
        // OBJECTID: item.wbsCode,
      },
    });
  });

  const markerLayer = new FeatureLayer({
    title: 'wbs_marks',
    source: graphics,
    objectIdField: 'OBJECTID',
    outFields: ['*'],
    popupEnabled: false,
    fields: [
      {
        name: 'OBJECTID',
        type: 'oid',
      },
    ].concat(
      [
        'applyLatitude',
        'applyLongitude',
        'monitorLatitude',
        'monitorLongitude',
        'officerLatitude',
        'officerLongitude',
        'supervisionLatitude',
        'supervisionLongitude',
        'handleLatitude',
        'handleLongitude',
        'wbsCode',
        'id',
        'type',
      ].map(name => {
        return {
          name,
          type: 'string',
        };
      }),
    ),
    screenSizePerspectiveEnabled: false,
    renderer: {
      type: 'unique-value', // autocasts as new UniqueValueRenderer()
      field: 'type',
      uniqueValueInfos: [
        {
          value: '质量问题',
          // href: './images/质量问题.svg',
          symbol: {
            type: 'point-3d', // autocasts as new PointSymbol3D()
            symbolLayers: [
              {
                type: 'icon', // autocasts as new IconSymbol3DLayer()
                resource: {
                  href: './images/质量问题.svg',
                },
                size: 20,
                outline: {
                  color: 'white',
                  size: 2,
                },
              },
            ],

            verticalOffset: {
              screenLength: 20,
              maxWorldLength: 200,
              minWorldLength: 35,
            },

            callout: {
              type: 'line', // autocasts as new LineCallout3D()
              color: 'white',
              size: 2,
              border: {
                color: '#F48024',
              },
            },
          },
        },
        {
          value: '安全巡检',
          // href: './images/安全问题.svg',
          symbol: {
            type: 'point-3d', // autocasts as new PointSymbol3D()
            symbolLayers: [
              {
                type: 'icon', // autocasts as new IconSymbol3DLayer()
                resource: {
                  href: './images/安全问题.svg',
                },
                size: 20,
                outline: {
                  color: 'white',
                  size: 2,
                },
              },
            ],

            verticalOffset: {
              screenLength: 20,
              maxWorldLength: 200,
              minWorldLength: 35,
            },

            callout: {
              type: 'line', // autocasts as new LineCallout3D()
              color: 'white',
              size: 2,
              border: {
                color: '#F48024',
              },
            },
          },
        },
      ],
    },

    elevationInfo: {
      mode: 'relative-to-scene',
    },
    labelingInfo: [
      {
        labelExpressionInfo: {
          // value: '{name}',
        },
        labelPlacement: 'above-center',
        symbol: {
          type: 'label-3d',
          symbolLayers: [
            {
              type: 'text',
              material: {
                color: 'white',
              },
              size: 10,
            },
          ],
        },
      },
    ],
  });

  const view = await viewUtils.isViewReady();
  view.map.add(markerLayer);

  // return customFeatureLayer;
}

function uniqueArrByField(arr, fieldName, extraProp = {}) {
  const fieldNameObj = {};
  const result: any[] = [];
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if (fieldNameObj[item[fieldName]]) {
      continue;
    }
    fieldNameObj[item[fieldName]] = true;
    result.push({ ...item, ...extraProp });
  }
  return result;
}
